home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 1999 August / SGI Freeware 1999 August.iso / dist / fw_ncurses.idb / usr / freeware / include / ncurses / cursesf.h.z / cursesf.h
Encoding:
C/C++ Source or Header  |  1999-07-16  |  24.1 KB  |  824 lines

  1. // * This makes emacs happy -*-Mode: C++;-*-
  2. /****************************************************************************
  3.  * Copyright (c) 1998 Free Software Foundation, Inc.                        *
  4.  *                                                                          *
  5.  * Permission is hereby granted, free of charge, to any person obtaining a  *
  6.  * copy of this software and associated documentation files (the            *
  7.  * "Software"), to deal in the Software without restriction, including      *
  8.  * without limitation the rights to use, copy, modify, merge, publish,      *
  9.  * distribute, distribute with modifications, sublicense, and/or sell       *
  10.  * copies of the Software, and to permit persons to whom the Software is    *
  11.  * furnished to do so, subject to the following conditions:                 *
  12.  *                                                                          *
  13.  * The above copyright notice and this permission notice shall be included  *
  14.  * in all copies or substantial portions of the Software.                   *
  15.  *                                                                          *
  16.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
  17.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
  18.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
  19.  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
  20.  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
  21.  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
  22.  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
  23.  *                                                                          *
  24.  * Except as contained in this notice, the name(s) of the above copyright   *
  25.  * holders shall not be used in advertising or otherwise to promote the     *
  26.  * sale, use or other dealings in this Software without prior written       *
  27.  * authorization.                                                           *
  28.  ****************************************************************************/
  29.  
  30. /****************************************************************************
  31.  *   Author: Juergen Pfeifer <Juergen.Pfeifer@T-Online.de> 1997             *
  32.  ****************************************************************************/
  33.  
  34. // $Id: cursesf.h,v 1.6 1998/02/11 12:13:41 tom Exp $
  35.  
  36. #ifndef _CURSESF_H
  37. #define _CURSESF_H
  38.  
  39. #include <cursesp.h>
  40.  
  41. extern "C" {
  42. #  include <form.h>
  43. }
  44. //
  45. // -------------------------------------------------------------------------
  46. // The abstract base class for buitin and user defined Fieldtypes.
  47. // -------------------------------------------------------------------------
  48. //
  49. class NCursesFormField; // forward declaration
  50.  
  51. // Class to represent builtin field types as well as C++ written new
  52. // fieldtypes (see classes UserDefineFieldType...
  53. class NCursesFieldType {
  54.   friend class NCursesFormField;
  55.  
  56. protected:
  57.   FIELDTYPE* fieldtype;
  58.  
  59.   inline void OnError(int err) const THROWS(NCursesFormException) {
  60.     if (err!=E_OK)
  61.       THROW(new NCursesFormException (err));
  62.   }
  63.  
  64.   NCursesFieldType(FIELDTYPE *f) : fieldtype(f) {
  65.   }
  66.  
  67.   virtual ~NCursesFieldType() {}
  68.  
  69.   // Set the fields f fieldtype to this one.
  70.   virtual void set(NCursesFormField& f) = 0;
  71.  
  72. public:
  73.   NCursesFieldType() : fieldtype((FIELDTYPE*)0) {
  74.   }
  75. };
  76.  
  77. //
  78. // -------------------------------------------------------------------------
  79. // The class representing a forms field, wrapping the lowlevel FIELD struct
  80. // -------------------------------------------------------------------------
  81. //
  82. class NCursesFormField {
  83.   friend class NCursesForm;
  84.  
  85. protected:
  86.   FIELD *field;              // lowlevel structure
  87.   NCursesFieldType* ftype;   // Associated field type
  88.  
  89.   // Error handler
  90.   inline void OnError (int err) const THROWS(NCursesFormException) {
  91.     if (err != E_OK)
  92.       THROW(new NCursesFormException (err));
  93.   }
  94.   
  95. public:
  96.   // Create a 'Null' field. Can be used to delimit a field list
  97.   NCursesFormField() 
  98.     : field((FIELD*)0), ftype((NCursesFieldType*)0) {
  99.   }
  100.  
  101.   // Create a new field
  102.   NCursesFormField (int rows,
  103.             int cols,
  104.             int first_row = 0,
  105.             int first_col = 0,
  106.             int offscreen_rows = 0,
  107.             int additional_buffers = 0) 
  108.     : ftype((NCursesFieldType*)0) {
  109.       field = ::new_field(rows,cols,first_row,first_col,
  110.               offscreen_rows, additional_buffers);
  111.       if (!field)
  112.     OnError(errno);
  113.   }
  114.   
  115.   virtual ~NCursesFormField ();
  116.  
  117.   // Duplicate the field at a new position
  118.   inline NCursesFormField* dup(int first_row, int first_col) {
  119.     NCursesFormField* f = new NCursesFormField();
  120.     if (!f)
  121.       OnError(E_SYSTEM_ERROR);
  122.     else {
  123.       f->ftype = ftype;
  124.       f->field = ::dup_field(field,first_row,first_col);
  125.       if (!f->field)
  126.     OnError(errno);
  127.     }
  128.     return f;
  129.   }
  130.  
  131.   // Link the field to a new location
  132.   inline NCursesFormField* link(int first_row, int first_col) {
  133.     NCursesFormField* f = new NCursesFormField();
  134.     if (!f)
  135.       OnError(E_SYSTEM_ERROR);
  136.     else {
  137.       f->ftype = ftype;
  138.       f->field = ::link_field(field,first_row,first_col);
  139.       if (!f->field)
  140.     OnError(errno);
  141.     }
  142.     return f;
  143.   }
  144.  
  145.   // Get the lowlevel field representation
  146.   inline FIELD* get_field() const {
  147.     return field;
  148.   }
  149.  
  150.   // Retrieve info about the field
  151.   inline void info(int& rows, int& cols,
  152.            int& first_row, int& first_col,
  153.            int& offscreen_rows, int& additional_buffers) const {
  154.     OnError(::field_info(field, &rows, &cols,
  155.              &first_row, &first_col,
  156.              &offscreen_rows, &additional_buffers));
  157.   }
  158.  
  159.   // Retrieve info about the fields dynamic properties.
  160.   inline void dynamic_info(int& dynamic_rows, int& dynamic_cols,
  161.                int& max_growth) const {
  162.     OnError(::dynamic_field_info(field, &dynamic_rows, &dynamic_cols,
  163.                  &max_growth));
  164.   }
  165.  
  166.   // For a dynamic field you may set the maximum growth limit.
  167.   // A zero means unlimited growth.
  168.   inline void set_maximum_growth(int growth = 0) {
  169.     OnError(::set_max_field(field,growth));
  170.   }
  171.  
  172.   // Move the field to a new position
  173.   inline void move(int row, int col) {
  174.     OnError(::move_field(field,row,col));
  175.   }
  176.  
  177.   // Mark the field to start a new page
  178.   inline void new_page(bool pageFlag = FALSE) {
  179.     OnError(::set_new_page(field,pageFlag));
  180.   }
  181.  
  182.   // Retrieve whether or not the field starts a new page.
  183.   inline bool is_new_page() const {
  184.     return ::new_page(field);
  185.   }
  186.  
  187.   // Set the justification for the field
  188.   inline void set_justification(int just) {
  189.     OnError(::set_field_just(field,just));
  190.   }
  191.  
  192.   // Retrieve the fields justification
  193.   inline int justification() const {
  194.     return ::field_just(field);
  195.   }
  196.   // Set the foreground attribute for the field
  197.   inline void set_foreground(chtype fore) {
  198.     OnError(::set_field_fore(field,fore));
  199.   }
  200.  
  201.   // Retrieve the fields foreground attribute
  202.   inline chtype fore() const {
  203.     return ::field_fore(field);
  204.   }
  205.  
  206.   // Set the background attribute for the field
  207.   inline void set_background(chtype back) {
  208.     OnError(::set_field_back(field,back));
  209.   }
  210.  
  211.   // Retrieve the fields background attribute
  212.   inline chtype back() const {
  213.     return ::field_back(field);
  214.   }
  215.  
  216.   // Set the padding character for the field
  217.   inline void set_pad_character(int pad) {
  218.     OnError(::set_field_pad(field,pad));
  219.   }
  220.  
  221.   // Retrieve the fields padding character
  222.   inline int pad() const {
  223.     return ::field_pad(field);
  224.   }
  225.  
  226.   // Switch on the fields options
  227.   inline void options_on (Field_Options options) {
  228.     OnError (::field_opts_on (field, options));
  229.   }
  230.  
  231.   // Switch off the fields options
  232.   inline void options_off (Field_Options options) {
  233.     OnError (::field_opts_off (field, options));
  234.   }
  235.  
  236.   // Retrieve the fields options
  237.   inline Field_Options options () const {
  238.     return ::field_opts (field);
  239.   }
  240.  
  241.   // Set the fields options
  242.   inline void set_options (Field_Options options) {
  243.     OnError (::set_field_opts (field, options));
  244.   }
  245.  
  246.   // Mark the field as changed
  247.   inline void set_changed(bool changeFlag = TRUE) {
  248.     OnError(::set_field_status(field,changeFlag));
  249.   }
  250.  
  251.   // Test whether or not the field is marked as changed
  252.   inline bool changed() const {
  253.     return ::field_status(field);
  254.   }
  255.  
  256.   // Return the index of the field in the field array of a form
  257.   // or -1 if the field is not associated to a form
  258.   inline int index() const {
  259.     return ::field_index(field);
  260.   }
  261.  
  262.   // Store a value in a fields buffer. The default buffer is nr. 0
  263.   inline void set_value(const char *val, int buffer = 0) {
  264.     OnError(::set_field_buffer(field,buffer,val));
  265.   }
  266.  
  267.   // Retrieve the value of a fields buffer. The defaukt buffer is nr. 0
  268.   inline char* value(int buffer = 0) const {
  269.     return ::field_buffer(field,buffer);
  270.   }
  271.  
  272.   // Set the validation type of the field.
  273.   inline void set_fieldtype(NCursesFieldType& f) {
  274.     ftype = &f;
  275.     f.set(*this); // A good friend may do that...
  276.   }
  277.  
  278.   // Retrieve the validation type of the field.
  279.   inline NCursesFieldType* fieldtype() const {
  280.     return ftype;
  281.   }
  282.  
  283. };
  284.  
  285. //
  286. // -------------------------------------------------------------------------
  287. // The class representing a form, wrapping the lowlevel FORM struct
  288. // -------------------------------------------------------------------------
  289. //
  290. class NCursesForm : public NCursesPanel {
  291. protected:
  292.   FORM* form;  // the lowlevel structure
  293.  
  294. private:
  295.   NCursesWindow* sub;   // the subwindow object
  296.   bool b_sub_owner;     // is this our own subwindow?
  297.   bool b_framed;        // has the form a border?
  298.   bool b_autoDelete;    // Delete fields when deleting form?
  299.  
  300.   NCursesFormField** my_fields; // The array of fields for this form
  301.  
  302.   // This structure is used for the form's user data field to link the
  303.   // FORM* to the C++ object and to provide extra space for a user pointer.
  304.   typedef struct {
  305.     void*              m_user;      // the pointer for the user's data
  306.     const NCursesForm* m_back;      // backward pointer to C++ object
  307.     const FORM*        m_owner;
  308.   } UserHook;
  309.  
  310.   // Get the backward pointer to the C++ object from a FORM
  311.   static inline NCursesForm* getHook(const FORM *f) {
  312.     UserHook* hook = (UserHook*)::form_userptr(f);
  313.     assert(hook && hook->m_owner==f);
  314.     return (NCursesForm*)(hook->m_back);
  315.   }
  316.  
  317.   // This are the built-in hook functions in this C++ binding. In C++ we use
  318.   // virtual member functions (see below On_..._Init and On_..._Termination)
  319.   // to provide this functionality in an object oriented manner.
  320.   static void frm_init(FORM *);
  321.   static void frm_term(FORM *);
  322.   static void fld_init(FORM *);
  323.   static void fld_term(FORM *);
  324.   
  325.   // Calculate FIELD* array for the menu
  326.   FIELD** mapFields(NCursesFormField* nfields[]);
  327.  
  328. protected:  
  329.   // internal routines 
  330.   inline void set_user(void *user) {
  331.     UserHook* uptr = (UserHook*)::form_userptr (form);
  332.     assert (uptr && uptr->m_back==this && uptr->m_owner==form);
  333.     uptr->m_user = user;
  334.   }
  335.  
  336.   inline void *get_user() {
  337.     UserHook* uptr = (UserHook*)::form_userptr (form);
  338.     assert (uptr && uptr->m_back==this && uptr->m_owner==form);
  339.     return uptr->m_user;
  340.   }  
  341.   
  342.   void InitForm (NCursesFormField* Fields[],
  343.          bool with_frame,
  344.          bool autoDeleteFields);
  345.  
  346.   inline void OnError (int err) const THROWS(NCursesFormException) {
  347.     if (err != E_OK)
  348.       THROW(new NCursesFormException (err));
  349.   }
  350.  
  351.   // this wraps the form_driver call.
  352.   virtual int driver (int c) ;
  353.  
  354.   // 'Internal' constructor, builds an object without association to a
  355.   // field array.
  356.   NCursesForm( int  lines, 
  357.            int  cols, 
  358.            int  begin_y = 0, 
  359.            int  begin_x = 0) 
  360.     : NCursesPanel(lines,cols,begin_y,begin_x), 
  361.       form ((FORM*)0) {
  362.   }
  363.   
  364. public:
  365.   // Create form for the default panel.
  366.   NCursesForm (NCursesFormField* Fields[],
  367.            bool with_frame=FALSE,         // reserve space for a frame?
  368.            bool autoDelete_Fields=FALSE)  // do automatic cleanup?
  369.     : NCursesPanel() {
  370.     InitForm(Fields, with_frame, autoDelete_Fields);
  371.   }
  372.  
  373.   // Create a form in a panel with the given position and size.
  374.   NCursesForm (NCursesFormField* Fields[],
  375.            int  lines, 
  376.            int  cols, 
  377.            int  begin_y, 
  378.            int  begin_x,
  379.            bool with_frame=FALSE,        // reserve space for a frame?
  380.            bool autoDelete_Fields=FALSE) // do automatic cleanup?
  381.     : NCursesPanel(lines, cols, begin_y, begin_x) {
  382.       InitForm(Fields, with_frame, autoDelete_Fields);
  383.   }
  384.  
  385.   virtual ~NCursesForm();
  386.  
  387.   // Set the default attributes for the form
  388.   virtual void setDefaultAttributes();
  389.  
  390.   // Retrieve current field of the form.
  391.   inline NCursesFormField* current_field() const {
  392.     return my_fields[::field_index(::current_field(form))];
  393.   }
  394.  
  395.   // Set the forms subwindow
  396.   void setSubWindow(NCursesWindow& sub);
  397.  
  398.   // Set these fields for the form
  399.   inline void setFields(NCursesFormField* Fields[]) {
  400.     OnError(::set_form_fields(form,mapFields(Fields)));    
  401.   }
  402.  
  403.   // Remove the form from the screen
  404.   inline void unpost (void) { 
  405.     OnError (::unpost_form (form)); 
  406.   }
  407.   
  408.   // Post the form to the screen if flag is true, unpost it otherwise
  409.   inline void post(bool flag = TRUE) {
  410.     OnError (flag ? ::post_form(form) : ::unpost_form (form)); 
  411.   }
  412.  
  413.   // Decorations
  414.   inline void frame(const char *title=NULL, const char* btitle=NULL) {
  415.     if (b_framed)
  416.       NCursesPanel::frame(title,btitle);
  417.     else
  418.       OnError(E_SYSTEM_ERROR);
  419.   }
  420.  
  421.   inline void boldframe(const char *title=NULL, const char* btitle=NULL) {
  422.     if (b_framed)
  423.       NCursesPanel::boldframe(title,btitle);
  424.     else
  425.       OnError(E_SYSTEM_ERROR);
  426.   }
  427.   
  428.   inline void label(const char *topLabel, const char *bottomLabel) {
  429.     if (b_framed)
  430.       NCursesPanel::label(topLabel,bottomLabel);
  431.     else
  432.       OnError(E_SYSTEM_ERROR);
  433.   }
  434.  
  435.   // -----
  436.   // Hooks
  437.   // -----
  438.  
  439.   // Called after the form gets repositioned in its window.
  440.   // This is especially true if the form is posted.
  441.   virtual void On_Form_Init();
  442.  
  443.   // Called before the form gets repositioned in its window.
  444.   // This is especially true if the form is unposted.
  445.   virtual void On_Form_Termination();
  446.  
  447.   // Called after the field became the current field
  448.   virtual void On_Field_Init(NCursesFormField& field);
  449.  
  450.   // Called before this field is left as current field.
  451.   virtual void On_Field_Termination(NCursesFormField& field);
  452.  
  453.   // Calculate required window size for the form.
  454.   void scale(int& rows, int& cols) const {
  455.     OnError(::scale_form(form,&rows,&cols));
  456.   }
  457.  
  458.   // Retrieve number of fields in the form.
  459.   int count() const {
  460.     return ::field_count(form);
  461.   }
  462.  
  463.   // Make the page the current page of the form.
  464.   void set_page(int page) {
  465.     OnError(::set_form_page(form,page));
  466.   }
  467.  
  468.   // Retrieve current page number
  469.   int page() const {
  470.     return ::form_page(form);
  471.   }
  472.  
  473.   // Switch on the forms options
  474.   inline void options_on (Form_Options options) {
  475.     OnError (::form_opts_on (form, options));
  476.   }
  477.  
  478.   // Switch off the forms options
  479.   inline void options_off (Form_Options options) {
  480.     OnError (::form_opts_off (form, options));
  481.   }
  482.  
  483.   // Retrieve the forms options
  484.   inline Form_Options options () const {
  485.     return ::form_opts (form);
  486.   }
  487.  
  488.   // Set the forms options
  489.   inline void set_options (Form_Options options) {
  490.     OnError (::set_form_opts (form, options));
  491.   }
  492.  
  493.   // Are there more data in the current field after the data shown
  494.   inline bool data_ahead() const {
  495.     return ::data_ahead(form);
  496.   }
  497.  
  498.   // Are there more data in the current field before the data shown
  499.   inline bool data_behind() const {
  500.     return ::data_behind(form);
  501.   }
  502.  
  503.   // Position the cursor to the current field
  504.   inline void position_cursor () {
  505.     OnError (::pos_form_cursor (form));
  506.   }
  507.   // Set the current field
  508.   inline void set_current(NCursesFormField& F) {
  509.     OnError (::set_current_field(form, F.field));
  510.   }
  511.  
  512.   // Provide a default key virtualization. Translate the keyboard
  513.   // code c into a form request code.
  514.   // The default implementation provides a hopefully straightforward
  515.   // mapping for the most common keystrokes and form requests.
  516.   virtual int virtualize(int c);
  517.  
  518.   // Operators
  519.   inline NCursesFormField* operator[](int i) const {
  520.     if ( (i < 0) || (i >= ::field_count (form)) )
  521.       OnError (E_BAD_ARGUMENT);
  522.     return my_fields[i];
  523.   }
  524.  
  525.   // Perform the menu's operation
  526.   // Return the field where you left the form.
  527.   virtual NCursesFormField* operator()(void);
  528.  
  529.   // Exception handlers. The default is a Beep.
  530.   virtual void On_Request_Denied(int c) const;
  531.   virtual void On_Invalid_Field(int c) const;
  532.   virtual void On_Unknown_Command(int c) const;
  533.  
  534. };
  535.  
  536. //
  537. // -------------------------------------------------------------------------
  538. // This is the typical C++ typesafe way to allow to attach
  539. // user data to a field of a form. Its assumed that the user
  540. // data belongs to some class T. Use T as template argument
  541. // to create a UserField.
  542. // -------------------------------------------------------------------------
  543. template<class T> class NCursesUserField : public NCursesFormField
  544. {
  545. public:
  546.   NCursesUserField (int rows,
  547.             int cols,
  548.             int first_row = 0,
  549.             int first_col = 0,
  550.             const T* p_UserData = (T*)0,
  551.             int offscreen_rows = 0,
  552.             int additional_buffers = 0)
  553.     : NCursesFormField (rows, cols,
  554.             first_row, first_col,
  555.             offscreen_rows, additional_buffers) {
  556.       if (field)
  557.     OnError(::set_field_userptr(field,(void *)p_UserData));
  558.   }
  559.  
  560.   virtual ~NCursesUserField() {};
  561.  
  562.   inline const T* UserData (void) const {
  563.     return (const T*)::field_userptr (field);
  564.   }
  565.  
  566.   inline virtual void setUserData(const T* p_UserData) {
  567.     if (field)
  568.       OnError (::set_field_userptr (field, (void *)p_UserData));
  569.   }
  570. };
  571. //
  572. // -------------------------------------------------------------------------
  573. // The same mechanism is used to attach user data to a form
  574. // -------------------------------------------------------------------------
  575. //
  576. template<class T> class NCursesUserForm : public NCursesForm
  577. {
  578. protected:
  579.   // 'Internal' constructor, builds an object without association to a
  580.   // field array.
  581.   NCursesUserForm( int  lines, 
  582.            int  cols, 
  583.            int  begin_y = 0, 
  584.            int  begin_x = 0,
  585.            const T* p_UserData = (T*)0) 
  586.     : NCursesForm(lines,cols,begin_y,begin_x) {
  587.       if (form)
  588.     set_user ((void *)p_UserData);
  589.   }
  590.  
  591. public:
  592.   NCursesUserForm (NCursesFormField Fields[], 
  593.            bool with_frame=FALSE,
  594.            bool autoDelete_Fields=FALSE)
  595.     : NCursesForm (Fields, with_frame, autoDelete_Fields) {
  596.   };
  597.  
  598.   NCursesUserForm (NCursesFormField Fields[],
  599.            const T* p_UserData = (T*)0,
  600.            bool with_frame=FALSE,
  601.            bool autoDelete_Fields=FALSE)
  602.     : NCursesForm (Fields, with_frame, autoDelete_Fields) {
  603.       if (form)
  604.     set_user ((void *)p_UserData);
  605.   };
  606.   
  607.   NCursesUserForm (NCursesFormField Fields[],
  608.            int lines, 
  609.            int cols, 
  610.            int begin_y = 0, 
  611.            int begin_x = 0,
  612.            const T* p_UserData = (T*)0,
  613.            bool with_frame=FALSE,
  614.            bool autoDelete_Fields=FALSE)
  615.     : NCursesForm (Fields, lines, cols, begin_y, begin_x,
  616.            with_frame, autoDelete_Fields) {
  617.       if (form)
  618.     set_user ((void *)p_UserData);
  619.   };  
  620.   
  621.   virtual ~NCursesUserForm() {
  622.   };
  623.   
  624.   inline T* UserData (void) const {
  625.     return (T*)get_user ();
  626.   };
  627.  
  628.   inline virtual void setUserData (const T* p_UserData) {
  629.     if (form)
  630.       set_user ((void *)p_UserData);
  631.   }
  632.  
  633. };
  634. //
  635. // -------------------------------------------------------------------------
  636. // Builtin Fieldtypes
  637. // -------------------------------------------------------------------------
  638. //
  639. class Alpha_Field : public NCursesFieldType {
  640. private:
  641.   int min_field_width;
  642.  
  643.   void set(NCursesFormField& f) {
  644.     OnError(::set_field_type(f.get_field(),fieldtype,min_field_width));
  645.   }
  646.  
  647. public:
  648.   Alpha_Field(int width) 
  649.     : NCursesFieldType(TYPE_ALPHA),
  650.       min_field_width(width) {
  651.   }
  652. };
  653.  
  654. class Alphanumeric_Field : public NCursesFieldType {
  655. private:
  656.   int min_field_width;
  657.  
  658.   void set(NCursesFormField& f) {
  659.     OnError(::set_field_type(f.get_field(),fieldtype,min_field_width));
  660.   }
  661.  
  662. public:
  663.   Alphanumeric_Field(int width) 
  664.     : NCursesFieldType(TYPE_ALNUM),
  665.       min_field_width(width) {
  666.   }
  667. };
  668.  
  669. class Integer_Field : public NCursesFieldType {
  670. private:
  671.   int precision;
  672.   long lower_limit, upper_limit;
  673.  
  674.   void set(NCursesFormField& f) {
  675.     OnError(::set_field_type(f.get_field(),fieldtype,
  676.                  precision,lower_limit,upper_limit));
  677.   }
  678.  
  679. public:
  680.   Integer_Field(int prec, long low=0L, long high=0L)
  681.     : NCursesFieldType(TYPE_INTEGER), 
  682.       precision(prec), lower_limit(low), upper_limit(high) {
  683.   }
  684. };
  685.  
  686. class Numeric_Field : public NCursesFieldType {
  687. private:
  688.   int precision;
  689.   double lower_limit, upper_limit;
  690.  
  691.   void set(NCursesFormField& f) {
  692.     OnError(::set_field_type(f.get_field(),fieldtype,
  693.                  precision,lower_limit,upper_limit));
  694.   }
  695.  
  696. public:
  697.   Numeric_Field(int prec, double low=0.0, double high=0.0)
  698.     : NCursesFieldType(TYPE_NUMERIC), 
  699.       precision(prec), lower_limit(low), upper_limit(high) {
  700.   }
  701. };
  702.  
  703. class Regular_Expression_Field : public NCursesFieldType {
  704. private:
  705.   char* regex;
  706.  
  707.   void set(NCursesFormField& f) {
  708.     OnError(::set_field_type(f.get_field(),fieldtype,regex));
  709.   }
  710.  
  711. public:
  712.   Regular_Expression_Field(const char *expr)
  713.     : NCursesFieldType(TYPE_REGEXP) {
  714.       regex = new char[1+::strlen(expr)];
  715.       strcpy(regex,expr);
  716.   }
  717.  
  718.   ~Regular_Expression_Field() {
  719.     delete[] regex;
  720.   }
  721. };
  722.  
  723. class Enumeration_Field : public NCursesFieldType {
  724. private:
  725.   char** list;
  726.   int case_sensitive;
  727.   int non_unique_matches;
  728.  
  729.   void set(NCursesFormField& f) {
  730.     OnError(::set_field_type(f.get_field(),fieldtype,
  731.                  list,case_sensitive,non_unique_matches));
  732.   }
  733. public:
  734.   Enumeration_Field(char* enums[],
  735.             bool case_sens=FALSE,
  736.             bool non_unique=FALSE)
  737.     : NCursesFieldType(TYPE_ENUM),
  738.       list(enums),
  739.       case_sensitive(case_sens?-1:0),
  740.       non_unique_matches(non_unique?-1:0) {
  741.   }
  742. };
  743.  
  744. class IPV4_Address_Field : public NCursesFieldType {
  745. private:
  746.   void set(NCursesFormField& f) {
  747.     OnError(::set_field_type(f.get_field(),fieldtype));
  748.   }
  749.  
  750. public:
  751.   IPV4_Address_Field() : NCursesFieldType(TYPE_IPV4) {
  752.   }
  753. };
  754. //
  755. // -------------------------------------------------------------------------
  756. // Abstract base class for User-Defined Fieldtypes
  757. // -------------------------------------------------------------------------
  758. //
  759. class UserDefinedFieldType : public NCursesFieldType {
  760.   friend class UDF_Init; // Internal helper to set up statics 
  761. private:
  762.   // For all C++ defined fieldtypes we need only one generic lowlevel
  763.   // FIELDTYPE* element.
  764.   static FIELDTYPE* generic_fieldtype; 
  765.  
  766. protected:
  767.   // This are the functions required by the low level libforms functions
  768.   // to construct a fieldtype.
  769.   static bool fcheck(FIELD *, const void*);
  770.   static bool ccheck(int c, const void *);
  771.   static void* makearg(va_list*);
  772.  
  773.   void set(NCursesFormField& f) {
  774.     OnError(::set_field_type(f.get_field(),fieldtype,&f));
  775.   }
  776.  
  777. protected:
  778.   // Redefine this function to do a field validation. The argument
  779.   // is a reference to the field you should validate.
  780.   virtual bool field_check(NCursesFormField& f) = 0;
  781.  
  782.   // Redefine this function to do a character validation. The argument
  783.   // is the character to be validated.
  784.   virtual bool char_check (int c) = 0;
  785.  
  786. public:
  787.   UserDefinedFieldType() : NCursesFieldType(generic_fieldtype) {
  788.   }
  789. };
  790. //
  791. // -------------------------------------------------------------------------
  792. // Abstract base class for User-Defined Fieldtypes with Choice functions
  793. // -------------------------------------------------------------------------
  794. //
  795. class UserDefinedFieldType_With_Choice : public UserDefinedFieldType {
  796.   friend class UDF_Init; // Internal helper to set up statics 
  797. private:
  798.   // For all C++ defined fieldtypes with choice functions we need only one 
  799.   // generic lowlevel FIELDTYPE* element.
  800.   static FIELDTYPE* generic_fieldtype_with_choice;
  801.  
  802.   // This are the functions required by the low level libforms functions
  803.   // to construct a fieldtype with choice functions.
  804.   static bool next_choice(FIELD*, const void *);
  805.   static bool prev_choice(FIELD*, const void *);
  806.  
  807. protected:
  808.   // Redefine this function to do the retrieval of the next choice value.
  809.   // The argument is a reference to the field tobe examined.
  810.   virtual bool next    (NCursesFormField& f) = 0;
  811.  
  812.   // Redefine this function to do the retrieval of the previous choice value.
  813.   // The argument is a reference to the field tobe examined.
  814.   virtual bool previous(NCursesFormField& f) = 0;
  815.  
  816. public:
  817.   UserDefinedFieldType_With_Choice() {
  818.     fieldtype = generic_fieldtype_with_choice;
  819.   }
  820. };
  821.  
  822. #endif // _CURSESF_H
  823.  
  824.